package com.dycong.common.Lamda;

import com.dycong.common.Lamda.anno.User;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by Duke on 2016/12/8.
 */
public class LambdaMapReduce {

    private static List<User> users = Arrays.asList(
            new User(1, "张三", 12, User.Sex.MALE),
            new User(2, "李四", 21, User.Sex.FEMALE),
            new User(3, "王五", 32, User.Sex.MALE),
            new User(4, "赵六", 32, User.Sex.FEMALE));

    public static void main(String[] args) {
        int average = users.parallelStream().filter(o -> o.getSex() == User.Sex.MALE).mapToInt(User::getAge).sum();
        int average1 = users.parallelStream().filter(o -> o.getSex() == User.Sex.MALE).mapToInt(o -> o.getAge()).sum();

        /*此处每有一个用户，统计加2,按性别统计用户数*/
        Map<User.Sex, Integer> map = users.parallelStream().collect(Collectors.groupingBy(o -> o.getSex(), Collectors.summingInt(p -> 2)));
        System.out.println(map);

        /*按性别获取用户名称*/
        Map<User.Sex, List<String>> map1 = users.parallelStream().collect(Collectors.groupingBy(User::getSex, Collectors.mapping(User::getName, Collectors.toList())));
        System.out.println(map1);

        //按性别求年龄的总和
        Map<User.Sex, Integer> map2 = users.stream().collect(Collectors.groupingBy(User::getSex, Collectors.reducing(0, User::getAge, Integer::sum)));
        System.out.println(map2);

        //按性别求年龄的平均值
        Map<User.Sex, Double> map3 = users.parallelStream().collect(Collectors.groupingBy(o -> o.getSex(), Collectors.averagingInt(o -> o.getAge())));
        System.out.println(map3);

        //按性别分组，并得出每组数量
        Map<User.Sex, Long> mapX = users.stream().collect(Collectors.groupingBy(User::getSex, Collectors.counting()));
        System.out.println(mapX);
        //按性别求年龄的总和
        Map<User.Sex, List<Integer>> map4 = users.stream().collect(Collectors.groupingBy(User::getSex, Collectors.mapping(User::getAge, Collectors.toList())));
        System.out.println(map4);

        //性别去重集合
        List<User.Sex> sexes = users.stream().map(User::getSex).distinct().collect(Collectors.toList());

        //按照id->user组成 MAP
        Map<Integer, User> userMap = users.stream().collect(Collectors.toMap(User::getId, o -> o));
        //按照id->user组成 MAP Function.identity()
        Map<Integer, User> userMap2 = users.stream().collect(Collectors.toMap(User::getId, Function.identity()));

        /**
         * 按照id->user组成
         * param Function<? super T, ? extends K> keyMapper 产生 key
         * param Function<? super T, ? extends U> valueMapper 产生 value
         * param BinaryOperator<U>todo mergeFunction 当 keyMapper 发现对同一个 key 有多个 value 时进行合并的比较器
         * param Supplier<M>todo  mapSupplier 返回 MAP 的具体子类型 ，声明 TreeMap，生成就是TreeMap
         */
        Map<Integer, User> userMap3 = users.stream().collect(Collectors.toMap(User::getAge, Function.identity(), (x, y) -> x.getId() < y.getId() ? x : y, TreeMap::new));


        // mapToInt的pipeline后面可以是average,max,min,count,sum
        double avg = users.parallelStream().mapToInt(User::getAge)
                .average().getAsDouble();

        System.out.println("reduceAvg User Age: " + avg);

        double sum = users.parallelStream().mapToInt(User::getAge)
                .reduce(0, (x, y) -> x + y); // 可以简写为.sum()

        System.out.println("reduceSum User Age: " + sum);


    }


    public void test() {
        User user = new User();
        /*输出：0 null null 0 java的基本类型在作为类的成员变量时未手动初始化的话，会有默认值!!!作为局部变量时，不会有默认值!!!*/
        System.out.println("" + user.getAge() + user.getSex() + user.getName() + user.getId());
    }

}
